using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using System;
using System.Reflection;


#if UNITY_EDITOR
using UnityEditor;
#endif
public class NumberSprite : MonoBehaviour
{
    public enum Alignment { Left, Center, Right }
    public enum AutoType {None, AutoContent, AutoCharacter }
    [SerializeField] private Color color = Color.white;
    [SerializeField] private Sprite[] sprites; // 0-9 + - . , 万 亿 ...
    [SerializeField] private float spacing = 0f;
    [SerializeField] private Alignment alignment = Alignment.Left;
    [SerializeField]
    private List<CharAdapter> charAdapters = new();
    private readonly List<GameObject> objList = new();
    private float totalWidth;
    Dictionary<string, Sprite> charSpriteMap = new Dictionary<string, Sprite>();
    bool inited;
    float currentSpacing;
    [HideInInspector]
    public AutoType autoType = AutoType.None;

#if UNITY_EDITOR
    void Reset()
    {

        if (charAdapters.Count == 0)
        {
            var subClasses = typeof(CharAdapterHelper).Assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(CharAdapterHelper)));
           
            foreach (var subClass in subClasses)
            {
                var instance = ((CharAdapterHelper)Activator.CreateInstance(subClass)).GetCharAdapter();
                if (charAdapters.Find(x => x.TargetChar == instance.TargetChar) == null)
                { 
                    charAdapters.Add(instance);
                }
            }
        }
    }
#endif
    void Awake()
    {
        TryInit();
    }
    void TryInit()
    {
        if (inited) return;
        inited = true;
        for (int i = 0; i < sprites.Length; i++)
        {
            var item = sprites[i];
            charSpriteMap[item.name.ToString()] = item;
        }
        ReCollectChild();
    }

    /// <summary>
    /// 设置字符串内容，例如 "+123.45万"
    /// </summary>
    public void SetString(string content)
    {
        currentSpacing = spacing;
        TryInit();
        if (sprites == null || sprites.Length == 0 || string.IsNullOrEmpty(content)) return;

        ResetObjList();

        totalWidth = 0;
        for (int i = 0; i < content.Length; i++)
        {
            var c = content[i];
            var obj = GetOrCreateObject(i);
            obj.SetActive(true);

            var image = obj.GetComponent<Image>();
            image.sprite = GetSpriteByChar(c);
            image.color = color;
            image.SetNativeSize();

            totalWidth += image.rectTransform.sizeDelta.x;
            if (i > 0) totalWidth += currentSpacing;
        }

        UpdateLayout();
    }

    private GameObject GetOrCreateObject(int index)
    {
        if (index < objList.Count) return objList[index];

        var obj = new GameObject("Char_" + index, typeof(Image));
        obj.transform.SetParent(transform, false);
        obj.transform.localScale = Vector3.one;
        obj.GetComponent<Image>().raycastTarget = false;
        objList.Add(obj);
        return obj;
    }

    private void ResetObjList()
    {
        if (objList != null)
        {
            foreach (var obj in objList)
            {
                if (obj)
                {
                    obj.SetActive(false);
                }
            }
        }

    }

    private void UpdateLayout()
    {

        float x = 0;

        // 自动调整字符宽度
        var container = GetComponent<RectTransform>();
        if(autoType == AutoType.AutoCharacter)
        {
            if (totalWidth > container.sizeDelta.x)
            {
                var characterWidthMultiple = container.sizeDelta.x / totalWidth;
                for (int i = 0; i < objList.Count; i++)
                {
                    var obj = objList[i];
                    if (!obj.activeSelf) continue;
                    var rt = obj.GetComponent<RectTransform>();
                    rt.sizeDelta = rt.sizeDelta * characterWidthMultiple;
                }
                currentSpacing = currentSpacing * characterWidthMultiple;
            }
            totalWidth = container.sizeDelta.x;

        }
        else if(autoType == AutoType.AutoContent)
        {
            //调整容器宽度
            container.sizeDelta = new Vector2(totalWidth, container.sizeDelta.y);
        }
        //设置对齐方式
        if (alignment == Alignment.Left)
        {
            x = 0;
            for (int i = 0; i < objList.Count; i++)
            {
                var obj = objList[i];
                if (!obj.activeSelf) continue;
                var rt = obj.GetComponent<RectTransform>();
                rt.pivot = new Vector2(0, 0.5f);
                rt.anchorMin = rt.anchorMax = new Vector2(0, 0.5f);
                rt.anchoredPosition = new Vector2(x, 0);
                x += rt.sizeDelta.x + currentSpacing;
            }
        }
        if (alignment == Alignment.Right)
        {
            x = 0;
            for (int i = objList.Count-1; i >= 0; i--)
            {
                var obj = objList[i];
                if (!obj.activeSelf) continue;

                var rt = obj.GetComponent<RectTransform>();
                rt.pivot = new Vector2(1, 0.5f);
                rt.anchorMin = rt.anchorMax = new Vector2(1, 0.5f);
                rt.anchoredPosition = new Vector2(x, 0);
                x -= rt.sizeDelta.x - currentSpacing;
            }
        }
        if (alignment == Alignment.Center)
        {
            x = 0;
            for (int i = 0; i < objList.Count; i++)
            {
                var obj = objList[i];
                if (!obj.activeSelf) continue;
                var rt = obj.GetComponent<RectTransform>();
                x += rt.sizeDelta.x + currentSpacing;
            }
            x = -x * .5f;
            for (int i = 0; i < objList.Count; i++)
            {
                var obj = objList[i];
                if (!obj.activeSelf) continue;
                var rt = obj.GetComponent<RectTransform>();
                rt.pivot = new Vector2(0, 0.5f);
                rt.anchorMin = rt.anchorMax = new Vector2(.5f, 0.5f);
                rt.anchoredPosition = new Vector2(x, 0);
                x += rt.sizeDelta.x + currentSpacing;
            }
        }



        

    }

    private Sprite GetSpriteByChar(char c)
    {
        string key;
        var agent = charAdapters.Find(x => x.TargetChar == c);
        if (agent != null)
        {
            key = agent.AgentStr;
        }
        else
        {
            key = c.ToString();
        }
        if (charSpriteMap.TryGetValue(key, out var sprite))
            return sprite;

        return null;
    }
    public void TestShow(string str)
    {
        inited = false;
        ReCollectChild();
        SetString(str);
    }
    void ReCollectChild()
    { 
        objList.Clear();
        for (int i = 0; i < this.transform.childCount; i++)
        {
            var item = this.transform.GetChild(i);
            if (item.name.StartsWith("Char_"))
            {
                objList.Add(item.gameObject);
            }
        }
    }
    [HideInInspector] public string testStr = "12345";

}
#if UNITY_EDITOR
[CustomEditor(typeof(NumberSprite))]
public class NumberSpriteExtend : Editor
{


    Dictionary<char, CharAdapter> CharAdapterDic = new();
    private void OnEnable()
    {
        //CharAdapter 的所有子类
        var subClasses = typeof(CharAdapterHelper).Assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(CharAdapterHelper)));
        CharAdapterDic.Clear();
        foreach (var subClass in subClasses)
        {
            var instance = ((CharAdapterHelper)Activator.CreateInstance(subClass)).GetCharAdapter();
            CharAdapterDic[instance.TargetChar] = instance;
        }
    }
    bool Foldout = true;
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        //分割线
        GUIStyle centeredStyle = new GUIStyle();
        centeredStyle.alignment = TextAnchor.MiddleCenter; // 水平居中
        centeredStyle.normal.textColor = Color.black; // 可选：设置文字颜色
        centeredStyle.fontSize = 20;
        centeredStyle.fontStyle = FontStyle.Bold;

        GUILayout.Label("-------------extend option-------------",centeredStyle);


        NumberSprite numberSprite = (NumberSprite)target;

        GUILayout.BeginHorizontal();
        //foldout
        Foldout = EditorGUILayout.Foldout(Foldout, "Add CharAdapterPresets",true);
        if (GUILayout.Button("AddAll"))
        {
            foreach (var item in CharAdapterDic)
            {
                AddAdapter(item.Value, numberSprite);
            }
            // 刷新 Unity 编辑器
            EditorUtility.SetDirty(numberSprite);
        }
        GUILayout.EndHorizontal();
        if (Foldout)
        {
            foreach (var item in CharAdapterDic)
            {
                if (GUILayout.Button($"{item.Value.AgentStr}->{item.Key.ToString()}"))
                {
                    AddAdapter(item.Value, numberSprite);
                    // 刷新 Unity 编辑器
                    EditorUtility.SetDirty(numberSprite);
                }
            }
        }
        //单选 AutoType
        numberSprite.autoType = (NumberSprite.AutoType)EditorGUILayout.EnumPopup("AutoType", numberSprite.autoType);
        GUILayout.BeginHorizontal();
        numberSprite.testStr = GUILayout.TextField(numberSprite.testStr);

        Color originalColor = GUI.backgroundColor;
        GUI.backgroundColor = Color.yellow;

        if (GUILayout.Button("测试String"))
        {
            numberSprite.TestShow(numberSprite.testStr);
            // 刷新 Unity 编辑器
            EditorUtility.SetDirty(numberSprite);
        }
        GUI.backgroundColor = originalColor; // 恢复原来的颜色
        GUILayout.EndHorizontal();
        
    }
    void AddAdapter(CharAdapter charAdapter, NumberSprite numberSprite)
    {
        var adapter =charAdapter;
        // 反射获取 numberSprite.charAdapters
        var charAdaptersField = typeof(NumberSprite).GetField("charAdapters", BindingFlags.Instance | BindingFlags.NonPublic);
        var charAdapters = (List<CharAdapter>)charAdaptersField.GetValue(numberSprite);
        // 检查是否已经存在相同的 TargetChar 的 CharAdapter
        var existingAdapter = charAdapters.Find(a => a.TargetChar == adapter.TargetChar);
        if (existingAdapter != null)
        {
            // 如果存在，更新 AgentStr
            existingAdapter.AgentStr = adapter.AgentStr;
        }
        else
        {
            // 如果不存在，添加新的 CharAdapter
            charAdapters.Add(adapter);
        }
        // 保存修改
        charAdaptersField.SetValue(numberSprite, charAdapters);
    }
}
#endif